#!/bin/bash

set -e

function sigterm_handler() {
    echo "SIGTERM signal received, try to gracefully shutdown all services..."
    gitlab-ctl stop
}

function failed_pg_upgrade() {
    echo 'Upgrading the existing database failed and was reverted.'
    echo 'Please check the output, and open an issue at:'
    echo 'https://gitlab.com/gitlab-org/omnibus-gitlab/issues'
    echo 'If you would like to restart the instance without attempting to'
    echo 'upgrade, add the following to your docker command:'
    echo '-e GITLAB_SKIP_PG_UPGRADE=true'
    exit 1
}

function clean_stale_pids() {
    # cleanup known pid/socket files
    for x in /opt/gitlab/sv /run ; do
        # find
        #  - any (s)ocket or regular (f)ile
        #  - by the name of "*.pid" or "socket.?"
        #  - and delete them
        find $x \
            \( \
              -type f \
              -o -type s \
            \) \(\
              -name pid \
              -o -name "*.pid" \
              -o -name "socket.?" \
            \) \
            -delete ;
    done
}

function detect_unclean_start() {
    set +e
    echo "Cleaning stale PIDs & sockets"
    clean_stale_pids
    set -e
}

# Make sure that there is no unmigrated data to hashed storage.
function unmigrated_data_check() {
    set +e

    echo "Checking for unmigrated data on legacy storage"
    found=$(MAX_DATABASE_CONNECTION_CHECKS=5 gitlab-rake gitlab:storage:legacy_attachments gitlab:storage:legacy_projects 2>&1);

    if [ $? -ne 0 ]; then
        echo "Upgrade failed. Could not check for unmigrated data on legacy storage."
        echo ""
        echo $found
        echo ""
        echo ""
        echo "If you would like to restart the instance without performing this"
        echo "check, add the following to your docker command:"
        echo "-e GITLAB_SKIP_UNMIGRATED_DATA_CHECK=true"
        echo ""
        exit 1
    fi

    if ! (echo $found | grep 'Found 0 attachments' && echo $found | grep 'Found 0 projects') > /dev/null 2>&1; then
        echo
        echo "Legacy storage is no longer supported. Please migrate your data to hashed storage."
        echo "Check https://docs.gitlab.com/ee/administration/raketasks/storage.html#migrate-to-hashed-storage for details."
        echo ""
        echo "Upgrade failed. Retry the upgrade after migrating your data to hashed storage."
        exit 1
    fi

    set -e
}

trap "sigterm_handler; exit" TERM

source /RELEASE
echo "Thank you for using GitLab Docker Image!"
echo "Current version: $RELEASE_PACKAGE=$RELEASE_VERSION"
echo ""
if [[ "$PACKAGECLOUD_REPO" == "unstable" ]]; then
	echo "You are using UNSTABLE version of $RELEASE_PACKAGE!"
	echo ""
fi
echo "Configure GitLab for your system by editing /etc/gitlab/gitlab.rb file"
echo "And restart this container to reload settings."
echo "To do it use docker exec:"
echo
echo "  docker exec -it gitlab editor /etc/gitlab/gitlab.rb"
echo "  docker restart gitlab"
echo
echo "For a comprehensive list of configuration options please see the Omnibus GitLab readme"
echo "https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md"
echo
echo "If this container fails to start due to permission problems try to fix it by executing:"
echo
echo "  docker exec -it gitlab update-permissions"
echo "  docker restart gitlab"
echo
sleep 3s

# Run unclean start detection & cleanup
detect_unclean_start

# Legacy block to be removed on 17.0. See: https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/7035
# It re-adds support for rsa key types which was removed on 16.0 without going
# through the proper deprecation process.
if [ "${GITLAB_ALLOW_SHA1_RSA}" == 'true' ]; then
  printf '\n# Enabled/Disabled via GITLAB_ALLOW_SHA1_RSA=[true/false]\nHostKeyAlgorithms +ssh-rsa\nPubkeyAcceptedKeyTypes +ssh-rsa' >> /assets/sshd_config
fi

# Check if this is a valid upgrade path
# If the VERSION file doesn't exist, then this is not an upgrade
if old_version=$(cat /var/opt/gitlab/gitlab-rails/VERSION)
then
    GITLAB_UPGRADE='true'
    new_version=$(awk '/^gitlab-(ce|ee|jh)/ {print $NF}' /opt/gitlab/version-manifest.txt)
    MIN_VERSION="15.11" gitlab-ctl upgrade-check "${old_version}" "${new_version}"
fi

# Copy gitlab.rb for the first time
if [[ ! -e /etc/gitlab/gitlab.rb ]]; then
	echo "Installing gitlab.rb config..."
	cp /opt/gitlab/etc/gitlab.rb.template /etc/gitlab/gitlab.rb
	chmod 0600 /etc/gitlab/gitlab.rb
fi

# Generate ssh host key for the first time
if [[ ! -f /etc/gitlab/ssh_host_rsa_key ]]; then
	echo "Generating ssh_host_rsa_key..."
	ssh-keygen -f /etc/gitlab/ssh_host_rsa_key -N '' -t rsa
	chmod 0600 /etc/gitlab/ssh_host_rsa_key
fi
# sshd loads the keys from /etc/gitlab, but the GitLab backend looks for keys
# from within /etc/ssh
ln -fs /etc/gitlab/ssh_host_rsa_key.pub /etc/ssh/ssh_host_rsa_key.pub

if [[ ! -f /etc/gitlab/ssh_host_ecdsa_key ]]; then
	echo "Generating ssh_host_ecdsa_key..."
	ssh-keygen -f /etc/gitlab/ssh_host_ecdsa_key -N '' -t ecdsa
	chmod 0600 /etc/gitlab/ssh_host_ecdsa_key
fi
# sshd loads the keys from /etc/gitlab, but the GitLab backend looks for keys
# from within /etc/ssh
ln -fs /etc/gitlab/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub

if [[ ! -f /etc/gitlab/ssh_host_ed25519_key ]]; then
	echo "Generating ssh_host_ed25519_key..."
	ssh-keygen -f /etc/gitlab/ssh_host_ed25519_key -N '' -t ed25519
	chmod 0600 /etc/gitlab/ssh_host_ed25519_key
fi
# sshd loads the keys from /etc/gitlab, but the GitLab backend looks for keys
# from within /etc/ssh
ln -fs /etc/gitlab/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_ed25519_key.pub


# Remove all services, the reconfigure will create them
echo "Preparing services..."
rm -f /opt/gitlab/service/*
ln -s /opt/gitlab/sv/sshd /opt/gitlab/service
ln -sf /opt/gitlab/embedded/bin/sv /opt/gitlab/init/sshd
mkdir -p /var/run/sshd
mkdir -p /var/log/gitlab/sshd
mkdir -p /var/log/gitlab/reconfigure

if [ -n "${GITLAB_PRE_RECONFIGURE_SCRIPT+x}" ]; then
  echo "Running Pre Reconfigure Script..."
  eval "${GITLAB_PRE_RECONFIGURE_SCRIPT}"
fi

# Start service manager
echo "Starting services..."
GITLAB_OMNIBUS_CONFIG= /opt/gitlab/embedded/bin/runsvdir-start &

echo "Configuring GitLab..."
gitlab-ctl reconfigure

# Skip unmigrated data check if Puma and Sidekiq is not running
if [ ! -d /opt/gitlab/service/puma ] && [ ! -d /opt/gitlab/service/sidekiq ]; then
    echo
    echo "This node does not appear to be running puma and/or sidekiq services"
    echo "Skipping unmigrated data check, if you think this is an error exit now"
    echo

    GITLAB_SKIP_UNMIGRATED_DATA_CHECK='true'
fi

# Check if there are no unmigrated data to hashed storage if it is an upgrade
if [ "${GITLAB_UPGRADE}" == 'true' -a "${GITLAB_SKIP_UNMIGRATED_DATA_CHECK}" != 'true' ]; then
  unmigrated_data_check
fi

# This must be false when the opt-in PostgreSQL version is the default for pg-upgrade,
# otherwise it must be true.
ATTEMPT_AUTO_PG_UPGRADE='false'

# Make sure PostgreSQL is at the latest version.
# If it fails, print a message with a workaround and exit
if [ "${GITLAB_SKIP_PG_UPGRADE}" != 'true' -a "${ATTEMPT_AUTO_PG_UPGRADE}" != 'false' ]; then
    gitlab-ctl pg-upgrade -w --skip-disk-check || failed_pg_upgrade
fi

if [ -n "${GITLAB_POST_RECONFIGURE_SCRIPT+x}" ]; then
  echo "Running Post Reconfigure Script..."
  eval "${GITLAB_POST_RECONFIGURE_SCRIPT}"
fi

if [ "${GITLAB_SKIP_TAIL_LOGS}" != 'true' ]; then
  # Tail all logs
  gitlab-ctl tail &
fi

# Wait for SIGTERM
wait
